/**
 * 标尺
 */
function scRuler(type){
    var com = scCommon.instance();
    var crEle = com.crEle;
    
    var container = null;
    var ruler = null;
    var rect = null;
    var paper = null;

    /**
     * 分段宽度
     */
    var segmentsWidth = {
    };

    /**
     * type=top时的滑块位置, slidersLeft中的left指的是偏移量left
     */
    var slidersLeft = {
        //左侧上部滑块left位置
        top: 0,
        //左侧下部滑块left位置
        bottomLeft: 0,
        //右侧下部滑块left位置
        bottomRight: 0
    };

    /**
     * type=left时的滑块位置, slidersTop中的top指的是偏移量top
     */
    var slidersTop = {
        //上部滑块top位置
        top: 0,
        //下部滑块top位置
        bottom: 0
    };

    /**
     * 单位宽度
     */
    var unitLength = null;

    //type=top时，左侧上部滑块
    var sliderTop = null;
    //type=top时，左侧下部滑块
    var sliderBottomLeft = null;
    //type=top时，右侧下部滑块
    var sliderBottomRight = null;

    //type=left时，左侧上部滑块
    var sliderLeftTop = null;
    //type=left时，左侧下部滑块
    var sliderLeftBottom = null;

    /**
     * type=left, true:显示滑块
     */
    var showSlider = false;

    const sliderWidth = 10;
    const sliderHeight = 12;

    /**
     * 创建视图
     * @param {*} option 
     * @returns 
     */
    this.createView = function(option){
        if(type == "top"){
            createViewForTop.call(this, option);
        }else{
            createViewForLeft.call(this, option);
        }

        return container;
    }

    /**
     * type=top,创建对应视图
     * @param {*} option 
     */
    var createViewForTop = function(option){
        option = option ? option : {};

        rect = {...option.boundRect};
        paper = {...option.paper};

        ruler = crEle("div", "sc-ruler,sc-ruler-top");

        sliderTop = crEle("div", "sc-ruler-slider,sc-slider-top");
        sliderBottomLeft = crEle("div", "sc-ruler-slider,sc-slider-bottom-left");
        sliderBottomRight = crEle("div", "sc-ruler-slider,sc-slider-bottom-right");

        let slider = createSliderForTop();
        sliderTop.innerHTML = slider;

        slider = createSliderForTop({transform:"rotate(180deg)"});
        sliderBottomLeft.innerHTML = slider;

        slider = createSliderForTop({transform:"rotate(180deg)", fill:"#ddd"});
        sliderBottomRight.innerHTML = slider;

        ruler.appendChild(sliderTop);
        ruler.appendChild(sliderBottomLeft);
        ruler.appendChild(sliderBottomRight);

        if(container){
            container.innerHTML = "";
        }else{
            container = crEle("div", "sc-ruler-top-container");
        }

        container.appendChild(ruler);

        let segment1 = crEle("div", "sc-ruler-segment,sc-segment-left");
        let segment2 = crEle("div", "sc-ruler-segment,sc-segment-center");
        let segment3 = crEle("div", "sc-ruler-segment,sc-segment-right");

        ruler.appendChild(segment1);
        ruler.appendChild(segment2);
        ruler.appendChild(segment3);

        if(paper.size){
            //单位长度(每厘米像素宽度)
            let unitWidth = rect.width / paper.size.width;
            //单位长度(每厘米像素宽度，缩放比例为1的长度)
            unitLength = rect.width / (option.zoom ? option.zoom : 1) / paper.size.width;

            let padLeft = 0;
            let padRight = 0;

            if(paper.padding){
                padLeft = paper.padding.left * unitWidth;
                padRight = paper.padding.right * unitWidth;
            }

            widthCenter = rect.width - padLeft - padRight;

            segmentsWidth.left = padLeft;
            segmentsWidth.center = widthCenter;
            segmentsWidth.right = padRight;

            segment1.style.width = padLeft + "px";
            segment2.style.width = widthCenter + "px";
            segment3.style.width = padRight + "px";

            sliderTop.style.width = sliderWidth + "px";
            sliderBottomLeft.style.width = sliderTop.style.width;
            sliderBottomRight.style.width = sliderTop.style.width;
            
            slidersLeft.top = padLeft - sliderWidth / 2;
            slidersLeft.bottomLeft = slidersLeft.top;
            slidersLeft.bottomRight = padLeft + widthCenter - sliderWidth / 2;

            sliderTop.style.left = slidersLeft.top + "px";
            sliderBottomLeft.style.left = slidersLeft.bottomLeft + "px";
            sliderBottomRight.style.left = slidersLeft.bottomRight + "px";

            let len = Math.ceil(paper.size.width);

            segment1.appendChild(createCentimeter(len, unitWidth));
            segment2.appendChild(createCentimeter(len, unitWidth));
            segment3.appendChild(createCentimeter(len, unitWidth));

            bindSliderEventForTop([sliderTop, sliderBottomLeft, sliderBottomRight]);
            bindRulerEvent(ruler, type);
        }

        ruler.style.left = option.boundRect.left;
        ruler.style.width = option.boundRect.width;
    }

    /**
     * type=left,创建对应视图
     * @param {*} option 
     */
    var createViewForLeft = function(option){
        option = option ? option : {};

        rect = {...option.boundRect};
        paper = {...option.paper};

        if(ruler){
            ruler.innerHTML = "";
        }else{
            ruler = crEle("div", "sc-ruler,sc-ruler-left");
        }

        sliderLeftTop = crEle("div", "sc-ruler-slider,sc-slider-left-top");
        sliderLeftBottom = crEle("div", "sc-ruler-slider,sc-slider-left-bottom");

        let slider = createSliderForLeft({strokeWidth:2});
        sliderLeftTop.innerHTML = slider;

        slider = createSliderForLeft({strokeWidth:2, transform:"rotate(180deg)"});
        sliderLeftBottom.innerHTML = slider;

        ruler.appendChild(sliderLeftTop);
        ruler.appendChild(sliderLeftBottom);

        if(container){
            container.innerHTML = "";
        }else{
            container = crEle("div", "sc-ruler-left-container");
        }

        container.appendChild(ruler);
        
        let segment1 = crEle("div", "sc-ruler-segment,sc-segment-left");
        let segment2 = crEle("div", "sc-ruler-segment,sc-segment-center");
        let segment3 = crEle("div", "sc-ruler-segment,sc-segment-right");

        ruler.appendChild(segment1);
        ruler.appendChild(segment2);
        ruler.appendChild(segment3);

        if(paper.size){
            //单位长度(每厘米像素宽度)
            let unitHeight = rect.height / paper.size.height;
            //单位长度(每厘米像素宽度，缩放比例为1的长度)
            unitLength = rect.height / (option.zoom ? option.zoom : 1) / paper.size.height;

            let padTop = 0;
            let padBottom = 0;

            if(paper.padding){
                padTop = paper.padding.top * unitHeight;
                padBottom = paper.padding.bottom * unitHeight;
            }

            heightMiddle = rect.height - padTop - padBottom;

            segmentsWidth.left = padTop;
            segmentsWidth.center = heightMiddle;
            segmentsWidth.right = padBottom;

            segment1.style.height = padTop + "px";
            segment2.style.height = heightMiddle + "px";
            segment3.style.height = padBottom + "px";

            let len = Math.ceil(paper.size.height);

            segment1.appendChild(createCentimeter(len, null, unitHeight));
            segment2.appendChild(createCentimeter(len, null, unitHeight));
            segment3.appendChild(createCentimeter(len, null, unitHeight));

            slidersTop.top = unitHeight * paper.headTop - sliderHeight / 2;
            slidersTop.bottom = padTop + heightMiddle + padBottom - 
                unitHeight * paper.footBottom - sliderHeight / 2;

            sliderLeftTop.style.height = sliderHeight + "px";
            sliderLeftTop.style.top = slidersTop.top + "px";

            sliderLeftBottom.style.height = sliderLeftTop.style.height;
            sliderLeftBottom.style.top = slidersTop.bottom + "px";

            if(!showSlider){
                sliderLeftTop.style.display = "none";
                sliderLeftBottom.style.display = "none";
            }

            bindSliderEventForLeft([sliderLeftTop, sliderLeftBottom]);
            bindRulerEvent(ruler, type);
        }

        ruler.style.top = option.boundRect.top;
        ruler.style.height = option.boundRect.height;
    }

    /**
     * 创建厘米
     * @param {*} length 
     * @param {*} width
     * @param {*} height
     * @returns 
     */
    var createCentimeter = function(length, width, height){
        var cms = crEle("div", "sc-ruler-cms");
        var cm = null;
        var split = null;

        for(var i = 0; i < length; i++){
            cm = crEle("div", "sc-ruler-cm");

            if(width != null){
                cm.style.width = width + "px";
            }else if(height != null){
                cm.style.height = height + "px";
            }
            
            for(var j = 0; j < 5; j++){
                split = crEle("div", "sc-ruler-cm-split");

                if(j == 2){
                    let text = crEle("span", "sc-ruler-cm-title");
                    text.innerText = i + 1;

                    split.appendChild(text);
                }

                cm.appendChild(split);
            }

            cms.appendChild(cm);
        }

        return cms;
    }

    /**
     * 创建滑块
     * @param {*} style 
     * @returns 
     */
    var createSliderForTop = function(style){
        let styStr = styleToString(style ? style : {});

        return `<svg 
            class="icon" 
            style="${styStr}" 
            viewBox="0 0 200 200" 
            version="1.1" 
            xmlns="http://www.w3.org/2000/svg">
            <path d="M10 10 L190 10 L190 80 L100 190 L10 80 Z">
            </path>
            </svg>`;
    }

    /**
     * 创建滑块
     * @param {*} style
     */
    var createSliderForLeft = function(style){
        let styStr = styleToString(style ? style : {});

        return `<svg 
            class="icon" 
            style="${styStr}" 
            viewBox="0 0 200 100" 
            version="1.1" 
            xmlns="http://www.w3.org/2000/svg">
            <path d="M10 20 L190 20 L190 80 L170 80 L170 60 L30 60 L30 80 L10 80 Z">
            </path>
            </svg>`;
    }

    /**
     * 样式转字符串
     * @param {*} style 
     * @returns 
     */
    var styleToString = function(style){
        var styStr = "";

        if(style.fill){
            styStr += "fill:" + style.fill + ";";
        }else{
            styStr += "fill:#fff;";
        }

        if(style.stroke){
            styStr += "stroke:" + style.stroke + ";";
        }else{
            styStr += "stroke:#000;"
        }

        if(style.strokeWidth){
            styStr += "stroke-width:" + style.strokeWidth + ";";
        }else{
            styStr += "stroke-width:8px;"
        }

        if(style.transform){
            styStr += "transform:" + style.transform + ";";
        }

        return styStr;
    }

    var rulerRect = null;
    var currentSegment = null;
    var segmentLeft = null;
    var segmentCenter = null;
    var segmentRight = null;
    var segmentType = null;
    
    /**
     * 给标尺分段绑定事件
     * @param {*} ruler 
     * @param {*} type
     */
    var bindRulerEvent = function(ruler, type){
        segmentLeft = ruler.querySelector(".sc-segment-left");
        segmentCenter = ruler.querySelector(".sc-segment-center");
        segmentRight = ruler.querySelector(".sc-segment-right");

        let inRange = null;
        let startMoveSegment = null;

        if(type == "top"){
            inRange = function(e){
                if(!rulerRect){
                    rulerRect = getElementRect(ruler);
                }
    
                if(e.pageX >= rulerRect.left + segmentLeft.clientWidth - 2 &&
                    e.pageX <= rulerRect.left + segmentLeft.clientWidth + 2 &&
                    e.pageY >= rulerRect.top && e.pageY <= rulerRect.top + rulerRect.height){
    
                    return "left";
                }else if(e.pageX >= rulerRect.left + segmentLeft.clientWidth + segmentCenter.clientWidth - 2 &&
                    e.pageX <= rulerRect.left + segmentLeft.clientWidth + segmentCenter.clientWidth + 2 &&
                    e.pageY >= rulerRect.top && e.pageY <= rulerRect.top + rulerRect.height){
    
                    return "right";
                }
    
                return null;
            };
            startMoveSegment = startMoveSegmentForTop;
        }else{
            inRange = function(e){
                if(!rulerRect){
                    rulerRect = getElementRect(ruler);
                    resizeSegments();
                }
    
                if(e.pageY >= rulerRect.top + segmentLeft.clientHeight - 2 &&
                    e.pageY <= rulerRect.top + segmentLeft.clientHeight + 2 &&
                    e.pageX >= rulerRect.left && e.pageX <= rulerRect.left + rulerRect.width){
    
                    return "left";
                }else if(e.pageY >= rulerRect.top + segmentLeft.clientHeight + segmentCenter.clientHeight - 2 &&
                    e.pageY <= rulerRect.top + segmentLeft.clientHeight + segmentCenter.clientHeight + 2 &&
                    e.pageX >= rulerRect.left && e.pageX <= rulerRect.left + rulerRect.width){
    
                    return "right";
                }
    
                return null;
            };
            startMoveSegment = startMoveSegmentForLeft;
        }

        ruler.addEventListener("mousedown", (e)=>{
            segmentType = inRange(e);

            if(segmentType != null){
                startMoveSegment(segmentType, e);
                e.stopPropagation();
            }
        });

        ruler.addEventListener("mousemove", (e)=>{
            if(inRange(e) != null){
                ruler.style.cursor = type == "top" ? "w-resize" : "s-resize";
            }else{
                ruler.style.cursor = "default";
            }

            moveLineForSegment(e, type, segmentType);
        });

        ruler.addEventListener("mouseup", (e)=>{
            if(currentSegment){
                e.stopPropagation();

                removeAllLine();
                emitSegment();
            }
        });

        document.body.addEventListener("mousemove", (e)=>{
            moveLineForSegment(e, type, segmentType);
        });

        document.body.addEventListener("mouseup", ()=>{
            if(currentSegment){
                removeAllLine();
                emitSegment();
            }
        });
    }

    /**
     * 开始移动分段
     * @param {*} segmentType 
     */
    var startMoveSegmentForTop = function(segmentType, e){
        let left = parseFloat(ruler.style.left) 
            + parseFloat(segmentLeft.clientWidth);
        
        if(segmentType == "right"){
            currentSegment = segmentRight;
            left += parseFloat(segmentCenter.clientWidth);
        }else{
            currentSegment = segmentLeft;
        }

        let top = parseFloat(ruler.style.top) 
            + parseFloat(ruler.style.height);
            
        showLine({
            top: top,
            left: left,
            width: 0,
            height: 2000
        });

        startOffset = {
            lineLeft: parseFloat(currentLine.style.left),
            mouseLeft: e.pageX,
        };
    }

    /**
     * 开始移动分段
     * @param {*} segmentType 
     */
    var startMoveSegmentForLeft = function(segmentType, e){
        let top = parseFloat(ruler.style.top) 
            + parseFloat(segmentLeft.clientHeight);
        
        if(segmentType == "right"){
            currentSegment = segmentRight;
            top += parseFloat(segmentCenter.clientHeight);
        }else{
            currentSegment = segmentLeft;
        }
    
        let left = parseFloat(ruler.style.left) 
            + parseFloat(ruler.style.width);
            
        showLine({
            top: top,
            left: left,
            width: 3000,
            height: 0
        });

        startOffset = {
            lineTop: parseFloat(currentLine.style.top),
            mouseTop: e.pageY,
        };
    }

    /**
     * 移动参照线（分段）
     * @param {*} e 
     * @param {*} type
     * @param {*} segmentType
     */
    var moveLineForSegment = function(e, type, segmentType){
        if(!currentSegment) return;

        if(type == "top"){
            let moveWidth = e.pageX - startOffset.mouseLeft;

            if(segmentType == "left"){
                currentSegment.style.width = segmentsWidth.left + moveWidth + "px";
                segmentCenter.style.width = segmentsWidth.center - moveWidth + "px";

                sliderTop.style.left = slidersLeft.top + moveWidth + "px";
                sliderBottomLeft.style.left = slidersLeft.bottomLeft + moveWidth + "px";
            }else{
                currentSegment.style.width = segmentsWidth.right - moveWidth + "px";
                segmentCenter.style.width = segmentsWidth.center + moveWidth + "px";

                sliderBottomRight.style.left = slidersLeft.bottomRight + moveWidth + "px";
            }

            currentLine.style.left = startOffset.lineLeft + moveWidth + "px";
        }else{
            let moveHeight = e.pageY - startOffset.mouseTop;

            if(segmentType == "left"){
                currentSegment.style.height = segmentsWidth.left + moveHeight + "px";
                segmentCenter.style.height = segmentsWidth.center - moveHeight + "px";
            }else{
                currentSegment.style.height = segmentsWidth.right - moveHeight + "px";
                segmentCenter.style.height = segmentsWidth.center + moveHeight + "px";
            }

            currentLine.style.top = startOffset.lineTop + moveHeight + "px";
        }
    }

    var startOffset = null;
    var currentSlider = null;
    var currentLine = null;

    /**
     * 给滑块绑定事件
     * @param {*} sliders 
     */
    var bindSliderEventForTop = function(sliders){
        for(var i = 0; i < sliders.length; i++){
            let node = sliders[i];

            node.addEventListener("mousedown", (e)=>{
                currentSlider = node;

                let left = parseFloat(ruler.style.left) 
                    + parseFloat(node.style.left)
                    + parseFloat(node.style.width) / 2;
                
                let top = parseFloat(ruler.style.top) 
                    + parseFloat(ruler.style.height);
                    
                showLine({
                    top: top,
                    left: left - 0.5,
                    width: 0,
                    height: 2000
                });

                startOffset = {
                    sliderLeft: parseFloat(currentSlider.style.left),
                    lineLeft: parseFloat(currentLine.style.left),
                    mouseLeft: e.pageX,
                };

                e.stopPropagation();
            });

            node.addEventListener("mousemove", (e)=>{
                moveLineForTopSlider(e);
                e.stopPropagation();
            });

            node.addEventListener("mouseup", (e)=>{
                if(currentSlider){
                    e.stopPropagation();

                    let type = getSliderType();
                    removeAllLine();
                    emitSlider(type);
                }
            });
        }

        document.body.addEventListener("mousemove", (e)=>{
            moveLineForTopSlider(e);
        });

        document.body.addEventListener("mouseup", ()=>{
            if(currentSlider){
                let type = getSliderType();
                removeAllLine();
                emitSlider(type);
            }
        });
    }

    /**
     * 给滑块绑定事件
     * @param {*} sliders 
     */
    var bindSliderEventForLeft = function(sliders){
        for(var i = 0; i < sliders.length; i++){
            let node = sliders[i];

            node.addEventListener("mousedown", (e)=>{
                currentSlider = node;

                let left = parseFloat(ruler.clientLeft) 
                    + parseFloat(ruler.clientWidth);
                
                let top = parseFloat(ruler.style.top)
                    + parseFloat(node.style.top) 
                    + parseFloat(sliderHeight) / 2;
                    
                showLine({
                    top: top,
                    left: left,
                    width: 3000,
                    height: 0
                });

                startOffset = {
                    sliderTop: parseFloat(currentSlider.style.top),
                    lineTop: parseFloat(currentLine.style.top),
                    mouseTop: e.pageY,
                };

                e.stopPropagation();
            });

            node.addEventListener("mousemove", (e)=>{
                moveLineForLeftSlider(e);
                e.stopPropagation();
            });

            node.addEventListener("mouseup", (e)=>{
                if(currentSlider){
                    e.stopPropagation();

                    let type = getSliderType();
                    removeAllLine();
                    emitSlider(type);
                }
            });
        }

        document.body.addEventListener("mousemove", (e)=>{
            moveLineForLeftSlider(e);
        });

        document.body.addEventListener("mouseup", ()=>{
            if(currentSlider){
                let type = getSliderType();
                removeAllLine();
                emitSlider(type);
            }
        });
    }

    /**
     * 获取滑块类型
     * @returns 
     */
    var getSliderType = function(){
        if(currentSlider == sliderTop){
            return "top";
        }else if(currentSlider == sliderBottomLeft){
            return "bottomLeft";
        }else if(currentSlider == sliderBottomRight){
            return "bottomRight";
        }else if(currentSlider == sliderLeftTop){
            return "leftTop";
        }else if(currentSlider == sliderLeftBottom){
            return "leftBottom";
        }
    }

    /**
     * 显示参照线
     * @param {*} rect 
     */
    var showLine = function(rect){
        currentLine = container.querySelector(".sc-ruler-line");
        
        if(currentLine == null){
            currentLine = crEle("div", "sc-ruler-line");
            container.appendChild(currentLine);
        }

        currentLine.style.width = rect.width + "px";
        currentLine.style.top = rect.top + "px";
        currentLine.style.left = rect.left + "px";
        currentLine.style.height = rect.height + "px";
    }

    /**
     * 移动参照线（滑块）
     * @param {*} e 
     * @param {*} type
     */
    var moveLineForTopSlider = function(e){
        if(!currentSlider) return null;

        let moveWidth = e.pageX - startOffset.mouseLeft;
        let left = startOffset.sliderLeft + moveWidth + sliderWidth / 2;
        let classList = currentSlider.classList;

        if(classList.contains("sc-slider-top") || classList.contains("sc-slider-bottom-left")){
            let maxLeft = segmentsWidth.left + segmentsWidth.center * 2 / 4;
            if(left < 0 || left > maxLeft) {
                return;
            }
        }else if(classList.contains("sc-slider-bottom-right")){
            let minLeft = segmentsWidth.left + segmentsWidth.center * 3 / 4;
            let maxLeft = segmentsWidth.left + segmentsWidth.center + segmentsWidth.right;

            if(left < minLeft || left > maxLeft) {
                return;
            }
        }

        currentSlider.style.left = startOffset.sliderLeft + moveWidth + "px";
        currentLine.style.left = startOffset.lineLeft + moveWidth + "px";
    }

    /**
     * 移动参照线（滑块）
     * @param {*} e 
     * @param {*} type
     */
    var moveLineForLeftSlider = function(e){
        if(!currentSlider) return null;

        let moveHeight = e.pageY - startOffset.mouseTop;
        let top = startOffset.sliderTop + moveHeight + parseFloat(sliderHeight) / 2;
        let classList = currentSlider.classList;

        if(classList.contains("sc-slider-top") || classList.contains("sc-slider-left-top")){
            let maxTop = segmentsWidth.left + segmentsWidth.center * 2 / 4;
            if(top < 0 || top > maxTop) {
                return;
            }
        }else if(classList.contains("sc-slider-left-bottom")){
            let minTop = segmentsWidth.left + segmentsWidth.center * 3 / 4;
            let maxTop = segmentsWidth.left + segmentsWidth.center + segmentsWidth.right;

            if(top < minTop || top > maxTop) {
                return;
            }
        }

        currentSlider.style.top = startOffset.sliderTop + moveHeight + "px";
        currentLine.style.top = startOffset.lineTop + moveHeight + "px";
    }

    /**
     * 移除所有参照线
     */
    var removeAllLine = function(){
        startOffset = null;

        if(currentLine){
            if(currentLine.parentNode){
                currentLine.parentNode.removeChild(currentLine);
            }
            currentLine = null;
        }

        if(currentSlider){
            currentSlider = null;
            resizeSliders();
        }

        if(currentSegment != null){
            currentSegment = null;
            resizeSegments();
            resizeSliders();
        }
    }

    /**
     * 重新设置滑块位置
     */
    var resizeSliders = function(){
        if(type == "top"){
            slidersLeft.top = parseFloat(sliderTop.style.left);
            slidersLeft.bottomLeft = parseFloat(sliderBottomLeft.style.left);
            slidersLeft.bottomRight = parseFloat(sliderBottomRight.style.left);
        }else if(type == "left"){
            slidersTop.top = parseFloat(sliderLeftTop.style.top);
            slidersTop.bottom = parseFloat(sliderLeftBottom.style.top);
        }
    }

    /**
     * 重新设置各分段宽度
     */
    var resizeSegments = function(){
        if(type == "top"){
            segmentsWidth.left = parseFloat(segmentLeft.style.width);
            segmentsWidth.center = parseFloat(segmentCenter.style.width);
            segmentsWidth.right = parseFloat(segmentRight.style.width);
        }else{
            segmentsWidth.left = parseFloat(segmentLeft.style.height);
            segmentsWidth.center = parseFloat(segmentCenter.style.height);
            segmentsWidth.right = parseFloat(segmentRight.style.height);
        }
    }

    /**
     * 调整位置和大小
     * @param {*} boundRect 包围盒
     * @param {*} zoom 放大倍数
     */
    this.resize = function(boundRect, zoom){
        if(!boundRect) return;

        if(type == "top"){
            if(boundRect.left != null){
                ruler.style.left = boundRect.left + "px";
            }

            if(boundRect.width != null){
                ruler.style.width = boundRect.width + "px";
            }

            zoomNode("width", zoom);
        }else{
            if(boundRect.top != null){
                ruler.style.top = boundRect.top + "px";
            }
    
            if(boundRect.height != null){
                ruler.style.height = boundRect.height + "px";
            }

            zoomNode("height", zoom);
        }

        rulerRect = null;
    }

    /**
     * 放大指定比例的节点宽度或高度
     * @param {*} prop 宽度"width",高度"height"
     * @param {*} zoom 放大倍数
     */
    var zoomNode = function(prop, zoom){
        if(zoom == null) return;
 
        let segmentNodes = ruler.querySelectorAll(".sc-ruler-segment");
        let node = null;
        let segmentsLength = segmentsWidth.left + segmentsWidth.center + segmentsWidth.right;
        let ratio = parseFloat(ruler.style[prop]) / segmentsLength;

        for(let i = 0; i < segmentNodes.length; i++){
            node = segmentNodes[i];
            if(node.classList.contains("sc-segment-left")){
                node.style[prop] = segmentsWidth.left * ratio + "px";
            }else if(node.classList.contains("sc-segment-center")){
                node.style[prop] = segmentsWidth.center * ratio + "px";
            }else if(node.classList.contains("sc-segment-right")){
                node.style[prop] = segmentsWidth.right * ratio + "px";
            }
        }

        let cmNodes = ruler.querySelectorAll(".sc-ruler-cm");

        for(let i = 0; i < cmNodes.length; i++){
            cmNodes[i].style[prop] = unitLength * zoom + "px";
        }

        resizeSegments();

        if(prop == "width"){
            let sliderTop = ruler.querySelector(".sc-slider-top");
            sliderTop.style.left = (slidersLeft.top + sliderWidth / 2) * ratio -
                sliderWidth / 2 + "px";

            let sliderBottomLeft = ruler.querySelector(".sc-slider-bottom-left");
            sliderBottomLeft.style.left = (slidersLeft.bottomLeft + sliderWidth / 2) * ratio -
                sliderWidth / 2 + "px";

            let sliderBottomRight = ruler.querySelector(".sc-slider-bottom-right");
            sliderBottomRight.style.left = (slidersLeft.bottomRight + sliderWidth / 2) * ratio -
                sliderWidth / 2 + "px";

            resizeSliders();
        }else if(prop == "height"){
            let sliderLeftTop = ruler.querySelector(".sc-slider-left-top");
            sliderLeftTop.style.top = (slidersTop.top + sliderHeight / 2) * ratio -
                sliderHeight / 2 + "px";

            let sliderLeftBottom = ruler.querySelector(".sc-slider-left-bottom");
            sliderLeftBottom.style.top = (slidersTop.bottom + sliderHeight / 2) * ratio -
                sliderHeight / 2 + "px";

            resizeSliders();
        }
    }

    /**
     * 片段调整后发出消息
     */
    var emitSegment = function(){
        var param = { zoom: 1 };

        param.padding = {};

        if(type == "top"){
            if(segmentType == "left"){
                param.padding.left = segmentsWidth.left;
            }else if(segmentType == "right"){
                param.padding.right = segmentsWidth.right;
            }
        }else if(type == "left"){
            if(segmentType == "left"){
                param.padding.top = segmentsWidth.left;
            }else if(segmentType == "right"){
                param.padding.bottom = segmentsWidth.right;
            }
        }

        //不触发pageSetting命令的监听器
        param.notTriggerListener = true;

        triggerListener("change", "pageSetting", param);
    }

    /**
     * 滑块调整后发出消息
     * @param {*} sliderType
     */
    var emitSlider = function(sliderType){
        var param = {};
        var command = "setParagraphStyle";

        if(type == "top"){
            if(sliderType == "top"){
                param.textIndent = slidersLeft.top - segmentsWidth.left + sliderWidth / 2;
            }else if(sliderType == "bottomLeft"){
                param.leftWholeIndent = slidersLeft.bottomLeft - segmentsWidth.left + sliderWidth / 2;
            }else if(sliderType == "bottomRight"){
                param.rightWholeIndent = slidersLeft.bottomRight - 
                    segmentsWidth.left - segmentsWidth.center + sliderWidth / 2;
            }
        }else if(type == "left"){
            if(sliderType == "leftTop"){
                param.headTop = slidersTop.top + sliderHeight / 2;
                param.isHeadEditable = true;
                command = "pageSetting";
            }else if(sliderType == "leftBottom"){
                param.footBottom = segmentsWidth.left + segmentsWidth.center + segmentsWidth.right -
                    slidersTop.bottom + sliderHeight / 2;
                param.isHeadEditable = true;
                command = "pageSetting";
            }
        }

        triggerListener("change", command, param);
    }

    /**
     * 当前页面包围盒
     */
    var currentRect = null;

    /**
     * 比较两个包围盒是否相等
     * @param {*} rect1 
     * @param {*} rect2 
     */
    var equalRect = function(rect1, rect2){
        if(!rect1 || !rect2) return false;

        for(var i in rect1){
            if(rect1[i] != rect2[i]) return false;
        }

        return true;
    }

    /**
     * 通知
     * @param {*} eventType 
     * @param {*} param 
     */
    this.notify = function(eventType, param){
        if(!listener["beforeNotify"]) return;
        
        var executeCommand = listener["beforeNotify"][0];

        //加载、调整大小、放大缩小、滚动事件、配置修改、外部容器调整大小监听
        if("resize|zoom|settingChange|resizeObserver".indexOf(eventType) > -1){
            let rect = executeCommand("getEditBoundRect");
            if(equalRect(currentRect, rect)) return;

            currentRect = rect;
            
            this.resize(currentRect, eventType == "zoom" ? param : null);
        }
        //设置页面规格
        else if("load|pageSetting".indexOf(eventType) > -1){
            this.createView({
                boundRect: executeCommand("getEditBoundRect"),
                paper: executeCommand("getPageSetting"),
                zoom: param.zoom,
                resize: true
            });
        }
        //外部单击事件
        else if("mousedown|scroll".indexOf(eventType) > -1){
            let rect = executeCommand("getEditBoundRect");
            
            if(!equalRect(currentRect, rect)) {
                currentRect = rect;
                this.resize(currentRect, eventType == "zoom" ? param : null);
            }

            if(param && param.paragraph){
                setSliderPositionForTop(param.paragraph);
            }
        }
        //外部双击事件
        else if(eventType == "dblclick"){
            setSliderPositionForLeft(param);
        }
    }

    /**
     * 重新设置滑块的位置
     */
    var setSliderPositionForTop = function(paragraph){
        if(type != "top" || !paragraph) return;

        if(paragraph.textIndent != null){
            sliderTop.style.left = segmentsWidth.left + paragraph.textIndent - sliderWidth / 2 + "px";
        }
        if(paragraph.leftWholeIndent != null){
            sliderBottomLeft.style.left = segmentsWidth.left + paragraph.leftWholeIndent - sliderWidth / 2 + "px";
        }
        if(paragraph.rightWholeIndent != null){
            sliderBottomRight.style.left = 
                segmentsWidth.left + segmentsWidth.center + paragraph.rightWholeIndent - sliderWidth / 2 + "px";
        }

        resizeSliders();
    }

    /**
     * 重新设置滑块的位置
     */
    var setSliderPositionForLeft = function(param){
        if(type != "left") return;

        showSlider = param.isHeadEditable === true;

        if(param.isHeadEditable){
            sliderLeftTop.style.display = "block";
            sliderLeftBottom.style.display = "block";
        }else{
            sliderLeftTop.style.display = "none";
            sliderLeftBottom.style.display = "none";
        }
    }

    /**
     * 监听器
     */
    var listener = {};

    /**
     * 添加监听器
     * @param {*} name 
     * @param {*} callback 
     */
    this.addEventListener = function(name, callback){
        if(!listener[name]){
            listener[name] = [];
        }

        listener[name].push(callback);
    }

    /**
     * 文档增加多个监听
     * @param {*} names 
     * @param {*} callback 
     */
    this.addEventListeners = function(names, callback){
        for(var i in names){
            this.addEventListener(names[i], callback);
        }
    }

    /**
     * 触发监听器
     * @param {*} eventType 
     * @param {*} command
     * @param {*} value 
     */
    var triggerListener = function(eventType, command, value){
        if(!listener[eventType]) return;

        for(var i in listener[eventType]){
            listener[eventType][i](command, value);
        }
    }

    /**
     * 获取元素包围盒
     * @param {*} element 
     * @returns 
     */
    var getElementRect = function(element) {
        var left = element.offsetLeft;
        var top = element.offsetTop;

        var current = element.offsetParent;

        while (current) {
            left += current.offsetLeft;
            top += current.offsetTop;

            current = current.offsetParent;
        }

        return {
            left: left,
            top: top,
            width: parseFloat(element.clientWidth),
            height: parseFloat(element.clientHeight)
        };
    }
}